package fileUtils

import (
	"bufio"
	"fmt"
	"github.com/fsnotify/fsnotify"
	"log"
	"os"
	"path/filepath"
	"utilsx/tools/logUtils"
)

func addOrRmWatch(watch *fsnotify.Watcher, path string, status bool) {
	file, err := os.Stat(path)
	if status {
		logUtils.LogLn(3, "创建文件/目录 : ", path)
		//获取新创建文件的信息，如果是目录，则加入监控中
		if err == nil && file.IsDir() {
			watch.Add(path)
			logUtils.LogLn(2, "添加监控 : ", path)
		}

	} else {
		logUtils.LogLn(1, "删除文件/目录 : ", path)
		if err == nil && file.IsDir() {
			watch.Remove(path)
			logUtils.LogLn(2, "移除监控 : ", path)
		}
	}
}
func watchEvent(watch *fsnotify.Watcher) {
	for {
		select {
		case ev := <-watch.Events:
			{
				if ev.Op&fsnotify.Create == fsnotify.Create {
					addOrRmWatch(watch, ev.Name, true)
				}

				if ev.Op&fsnotify.Write == fsnotify.Write {
					//fmt.Println("写入文件 : ", ev.Name)
				}

				if ev.Op&fsnotify.Remove == fsnotify.Remove {
					addOrRmWatch(watch, ev.Name, false)

				}

				if ev.Op&fsnotify.Rename == fsnotify.Rename {
					//如果重命名文件是目录，则移除监控 ,注意这里无法使用os.Stat来判断是否是目录了
					//因为重命名后，go已经无法找到原文件来获取信息了,所以简单粗爆直接remove
					fmt.Println("重命名文件 : ", ev.Name)
					watch.Remove(ev.Name)
				}
				if ev.Op&fsnotify.Chmod == fsnotify.Chmod {
					fmt.Println("修改权限 : ", ev.Name)
				}
			}
		case err := <-watch.Errors:
			{
				fmt.Println("error : ", err)
				return
			}
		}
	}
}
func WatchDir(watch *fsnotify.Watcher, files []FileInfo) error {
	for _, file := range files {
		if file.IsDir {
			path, err := filepath.Abs(file.Path)
			if err != nil {
				return err
			}
			err = watch.Add(path)
			if err != nil {
				return err
			}
			logUtils.LogLn(3, "初始化文件监控 :", path)
		}
	}
	go watchEvent(watch) //协程
	return nil
}
func SaveFile(targetFile string, data []byte) {
	file, err := os.OpenFile(targetFile, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0677)
	if err != nil {
		panic(err)
		return
	}
	defer file.Close()
	write := bufio.NewWriter(file)
	write.Write(data)
	write.Flush()

}
func WatchFile(watch *fsnotify.Watcher, dir string, handle func(ev fsnotify.Event)) {
	//添加要监控的文件
	err := watch.Add(dir)
	if err != nil {
		log.Fatal(err)
	}
	//我们另启一个goroutine来处理监控对象的事件
	go func() {
		for {
			select {
			case ev := <-watch.Events:
				{
					handle(ev)
				}
			case err := <-watch.Errors:
				{
					log.Fatal("error : ", err)
					return
				}
			}
		}
	}()
}
